/*  

Cafechess Library: Cover basic chess programming needs, like GUI, Engine integration, 
FEN and PGN parsing.

                 \\|//
                 (o o)
--------------ooO-(_)-Ooo----------------------------------
Copyright (C) 2009  By Gregory A. Prentice Snoqualmie, WA
                    www.cafechess.org
                    cafechess@comcast.net
                      Oooo
--------------oooO----(  )---------------------------------
              (  )    (_/
               \_)

Microsoft Public License (Ms-PL)
               
Revisions:

Author        Date    Description:

*/
using System;

namespace Cafechess.Chess.Parsers
{
  #region GameParser

  /// <summary>
  /// This interface defines the minimum functionality that a game 
  /// parser must implement.  It does not have to have all the functionality
  /// present, but the interface must be delcared.
  /// <seealso cref="IGameParserEvents"/>
  /// </summary>
  public interface IGameParser
  {
    /// <summary>
    /// Name of the fileto parse.
    /// </summary>
    string Filename{ get;set;}
    /// <summary>
    /// Show what STATE with in the parser 
    /// that is currently active.
    /// </summary>
    GameParserState.State State{get;set;}
    /// <summary>
    /// Holds any header/game information that describes attributes
    /// of the game such as: Date, Players, ELO, ECO, Ratings, and others.
    /// Will contain valid data during the IGameParserEvents.tagParsed event.
    /// </summary>
    string Tag{get;}
    /// <summary>
    /// Will contain valid data during the IGameParserEvents.tagParsed event which
    /// represents the data associated with the game tag.  Also during the following
    /// events:
    ///   IGameParserEvents.nagParsed
    ///   IGameParserEvents.moveParsed
    ///   IGameParserEvents.commentParsed
    /// </summary>
    string Value{ get; }
    /// <summary>
    /// Executes the main loop for parsing out the games.
    /// </summary>
    void Parse();
    /// <summary>
    /// Used to register event handlers.
    /// </summary>
    /// <param name="ievents"></param>
    void AddEvents(IGameParserEvents ievents);
    /// <summary>
    /// Used to remove event handlers.
    /// </summary>
    /// <param name="ievents"></param>
    void RemoveEvents(IGameParserEvents ievents);
  }
  /// <summary>
  /// Defines all of the events that a game parser may call to
  /// listeners so that they may build a chess game.
  /// </summary>
  public interface IGameParserEvents
  {
    /// <summary>
    /// Called when a new game in the parsed data file has been located.
    /// </summary>
    /// <param name="iParser"></param>
    void NewGame(IGameParser iParser);
    /// <summary>
    /// Called when you are no longer parsing the header tags and are
    /// beginning to enter the parsing of the moves.
    /// </summary>
    /// <param name="iParser"></param>
    void ExitHeader(IGameParser iParser);
    /// <summary>
    /// Called when the parser is entering a variation.
    /// </summary>
    /// <param name="iParser"></param>
    void EnterVariation(IGameParser iParser);
    /// <summary>
    /// Calle when the parser is leaving a variation.
    /// </summary>
    /// <param name="iParser"></param>
    void ExitVariation(IGameParser iParser);
    /// <summary>
    /// Called when the parser is completely finished parsing a file.
    /// </summary>
    /// <param name="iParser"></param>
    void Starting(IGameParser iParser);
    /// <summary>
    /// Called when the parser is completely finished parsing a file.
    /// </summary>
    /// <param name="iParser"></param>
    void Finished(IGameParser iParser);
    /// <summary>
    /// Called when the parser has determined game header information
    /// such as Player names, ELO, ECO, Dates, and others.
    /// See the PGN standards documentation.
    /// </summary>
    /// <param name="iParser"></param>
    void TagParsed(IGameParser iParser);
    /// <summary>
    /// Called when the parser has determined a NAG comments based on PGN
    /// standards.
    /// </summary>
    /// <param name="iParser"></param>
    void NagParsed(IGameParser iParser);
    /// <summary>
    /// Called when the parser has determined a move is present.
    /// </summary>
    /// <param name="iParser"></param>
    void MoveParsed(IGameParser iParser);
    /// <summary>
    /// Called when the parser has determined a comment is present.
    /// </summary>
    /// <param name="iParser"></param>
    void CommentParsed(IGameParser iParser);
    /// <summary>
    /// Used to signal an end of game marker has been found ie 1/2-1/2, 1-0, 0-1
    /// </summary>
    /// <param name="iParser"></param>
    void EndMarker(IGameParser iParser);
  }
  /// <summary>
  /// Used for a IGameParser machines current state.
  /// </summary>
  public class GameParserState
  {
    /// <summary>
    /// The different states our parse may be in when firing events.
    /// </summary>
    public enum State
    {
      /// <summary>
      /// Parsing the header information
      /// </summary>
      HEADER, 
      /// <summary>
      /// Parsing the number of a move
      /// </summary>
      NUMBER, 
      /// <summary>
      /// Parsing the color to move
      /// </summary>
      COLOR,
      /// <summary>
      /// Parsing white's move information
      /// </summary>
      WHITE, 
      /// <summary>
      /// Parsing black's move information.
      /// </summary>
      BLACK, 
      /// <summary>
      /// Parsing a comment.
      /// </summary>
      COMMENT,
      /// <summary>
      /// Finished parsing a comment.
      /// </summary>
      ENDCOMMENT, 
      /// <summary>
      /// Parsing a NAG.
      /// </summary>
      NAGS,
      /// <summary>
      /// Convert a Nag to text.
      /// </summary>
      CONVERT_NAG,
      /// <summary>
      /// END.
      /// </summary>
      ENDMARKER 
    };  
  }
  #endregion
}
